package com.lincoln.framework.interceptor;

import com.lincoln.framework.common.Constant;
import com.lincoln.framework.annotation.MenuAuth;
import com.lincoln.framework.annotation.UnAuth;
import com.lincoln.framework.bean.SysLoginAdmin;
import com.lincoln.framework.common.WebUtils;
import com.lincoln.framework.entity.SysAdmin;
import com.lincoln.framework.entity.SysMenu;
import com.lincoln.framework.exception.NoRightsException;
import com.lincoln.framework.service.SysAdminService;
import com.lincoln.framework.service.SysMenuService;
import com.lincoln.framework.utils.FrameworkLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 系统端权限登录校验
 * 
 * @author zwm
 */
public class SysAuthInterceptor extends HandlerInterceptorAdapter {

	private static FrameworkLogger logger = FrameworkLogger.initFrameworkLogger(SysAuthInterceptor.class);

	@Autowired
	private SysAdminService adminService;

	@Autowired
	private SysMenuService sysMenuService;

	/**
	 * This implementation always returns {@code true}.
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 不需要校验类、方法跳过
		MenuAuth menuAuth = null;
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Class clasz = handlerMethod.getBean().getClass();
		request.setAttribute(Constant.SYS_REQUEST_URI, request.getRequestURI());

		if (clasz.isAnnotationPresent(UnAuth.class)) {
			return true;
		}
		Method[] methods = clasz.getMethods();
		for (Method method : methods) {
			if (method.isAnnotationPresent(RequestMapping.class)) {
				if (method.isAnnotationPresent(UnAuth.class)) {
					RequestMapping mapping = method.getAnnotation(RequestMapping.class);
					for (String str : mapping.path()) {
						if (request.getRequestURI().indexOf(str) != -1) {
							return true;
						}
					}
				} else if (method.isAnnotationPresent(MenuAuth.class)) { // 菜单校验获取菜单
					RequestMapping mapping = method.getAnnotation(RequestMapping.class);
					for (String str : mapping.path()) {
						if (request.getRequestURI().indexOf(str) != -1) {
							menuAuth = method.getAnnotation(MenuAuth.class);

							break;
						}
					}
					if (menuAuth == null) {
						for (String str : mapping.value()) {
							if (request.getRequestURI().indexOf(str) != -1) {
								menuAuth = method.getAnnotation(MenuAuth.class);
								break;
							}
						}
					}
					if (menuAuth != null) {
						break;
					}
				}
			}
		}

		SysLoginAdmin loginAdmin = WebUtils.getSysLoginAdmin();
		if (loginAdmin != null) {
			SysAdmin sysAdmin = adminService.getSysAdminById(loginAdmin.getId());
			if (sysAdmin != null) {
				if (sysAdmin.getStatus() == SysAdmin.STATUS_DISABLE) {
					throw new NoRightsException("账号已停用，请联系管理员");
				}
				if (sysAdmin.getSysRole() != null && menuAuth != null
						&& !loginAdmin.checkMenuAuth(request.getRequestURI(), menuAuth)) {
					throw new NoRightsException("无访问权限");
				}
				Integer menuId = loginAdmin.getSysRoleRights().getMenuIdByUri(request.getRequestURI());
				if (menuId != null) {
					request.setAttribute(Constant.SYS_REQUEST_MENU_ID, menuId);
					SysMenu menu = sysMenuService.getSysMenuById(menuId);
					if (menu != null && menu.getParentMenu() != null) {
						request.setAttribute(Constant.SYS_REQUEST_PARENT_MENU_ID, menu.getParentMenu().getId());
					}
				}
				return true;
			}
			throw new NoRightsException("账号不存在，请重新登录", Constant.ERRORTYPE_UNLOGIN);
		}

		throw new NoRightsException("账号未登录，请重新登录", Constant.ERRORTYPE_UNLOGIN);
	}

}
